Imports System
Imports System.Globalization
Imports System.Text
Imports System.Text.RegularExpressions

''' <summary>
''' Methods for regular expression manipulations.
''' </summary>
Public Class RegexUtil

#Region "Private constructor"

	Private Sub New()
		' Can't create instance!
	End Sub

#End Region

#Region "Patterns"

	Public Const Host As String = "([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?"
	Public Const IP As String = "^(([0-2]*[0-9]+[0-9]+)\.([0-2]*[0-9]+[0-9]+)\.([0-2]*[0-9]+[0-9]+)\.([0-2]*[0-9]+[0-9]+))$"
	Public Const Url As String = "(([\w]+:)?//)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?"
	Public Const Email As String = "^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$"
	Public Const Password As String = "^.{4,20}$"
	Public Const NoSpecialCharacters As String = "^[a-zA-Z0-9_\-\.]{2,9999}$"
	Public Const FilePictures As String = "^.+\.([jJ][pP][gG]|[gG][iI][fF]|[pP][nN][gG]|[bB][mM][pP])$"

#End Region

#Region "Methods"

	''' <summary>
	''' Test the specified value against a pattern.
	''' </summary>
	''' <returns>True if it matches, otherwise False.</returns>
	Public Shared Function Test(ByVal strInput As String, ByVal pattern As String) As Boolean

		Return Regex.IsMatch(strInput, pattern)

	End Function

	''' <summary>
	''' Extracts the text out of the specified html value.
	''' </summary>
	''' <returns>Plain text as String.</returns>
	Public Shared Function GetTextFromHtml(ByVal value As String) As String

		If String.IsNullOrEmpty(value) Then
			Return value
		End If

		value = Regex.Replace(value, "<[^>]*>", "", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
		value = Regex.Replace(value, "[<]", "", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
		value = Regex.Replace(value, "[>]", "", RegexOptions.IgnoreCase Or RegexOptions.Multiline)

		Return value

	End Function

	''' <summary>
	''' Extracts the title of the specified html document.
	''' </summary>
	''' <returns>Text inside <title></title> as String.</returns>
	Public Shared Function GetTitleFromHtml(ByVal value As String) As String

		If String.IsNullOrEmpty(value) Then
			Return value
		End If

		Dim length As Integer = value.Length
		Dim iStart As Integer = value.IndexOf("<title>", StringComparison.InvariantCultureIgnoreCase) + 7
		Dim iEnd As Integer = value.IndexOf("</title", StringComparison.InvariantCultureIgnoreCase)

		value = value.Substring(iStart, length - iStart)
		value = value.Substring(0, iEnd - iStart)

		Return value

	End Function

	''' <summary>
	''' Parses the value and inserts html link tags for all URLs, using _self as target.
	''' </summary>
	''' <returns>Parsed text with html links.</returns>
	Public Shared Function CreateLinksInHtml(ByVal value As String) As String

		Return CreateLinksInHtml(value, "_self")

	End Function

	''' <summary>
	''' Parses the value and inserts html link tags for all URLs, using the desired link target.
	''' </summary>
	''' <returns>Parsed text with html links.</returns>
	Public Shared Function CreateLinksInHtml(ByVal value As String, ByVal target As String) As String

		Dim r As New Regex("((www\.|(http|https|ftp|news|file)+\:\/\/)[&#95;.a-z0-9-]+\.[a-z0-9\/&#95;:@=.+?,##%&~-]*[^.|\'|\# |!|\(|?|,| |>|<|;|\)])", RegexOptions.IgnoreCase)
		Dim matches As MatchCollection = r.Matches(value)
		Dim i As Integer

		For i = 0 To matches.Count - 1

			Dim link As String = matches(i).Value
			Dim newLink As String = link

			If Not newLink.Substring(0, 7).ToLower().Equals("http://") Then
				newLink = "http://" & newLink
			End If

			value = value.Replace(link, "<a href=""" & newLink & """ target=""" & target & """>" & link & "</a>")

		Next

		Return value

	End Function

	''' <summary>
	''' Removes all accents from the specified text.
	''' </summary>
	''' <returns>Text without accents, as String.</returns>
	Public Shared Function RemoveAccents(ByVal value As String) As String

		Dim strNormalized As String = value.Normalize(NormalizationForm.FormD)
		Dim strBuilder As New StringBuilder()
		Dim i As Integer

		For i = 0 To strNormalized.Length - 1

			Dim c As Char = Convert.ToChar(strNormalized.Substring(i, 1))

			If CharUnicodeInfo.GetUnicodeCategory(c) <> UnicodeCategory.NonSpacingMark Then
				strBuilder.Append(c)
			End If

		Next

		Return strBuilder.ToString()

	End Function

	''' <summary>
	''' Removes all special characters and spaces from the specified text.
	''' </summary>
	''' <returns>Plain text, as String.</returns>
	Public Shared Function RemoveSpecialCharacters(ByVal value As String) As String

		Return RemoveSpecialCharacters(value, False)

	End Function

	''' <summary>
	''' Removes all special characters from the text, preserving spaces.
	''' </summary>
	''' <returns>Plain text, as String.</returns>
	Public Shared Function RemoveSpecialCharacters(ByVal value As String, ByVal preserveSpaces As Boolean) As String

		If preserveSpaces Then

			value = Regex.Replace(value, "[^ \w\.-]", "")

		Else

			value = Regex.Replace(value, "[^\w\.-]", "")

			While value.Contains(" ")
				value = value.Replace(" ", "")
			End While

		End If

		Return value

	End Function

#End Region

End Class